
/*
author:杨文超
email:yangwenchao@keynection.cn
*/
#include <stdio.h>
#include <inttypes.h>
#include <string.h>
#include <stdlib.h>

#include <arpa/inet.h>
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "geminai_usbh_modem_board.h"
#include "geminai_usbh_modem_wifi.h"
#include "esp32_s3_usb_otg.h"
#include "geminai_sntp.h"
#include "geminai_sdklink_connect.h"
#include "geminai_mqtt_cache.h"
#include "geminai_selfcheck.h"
#include "geminai_modbus.h"
#include "geminai_para.h"
#include "geminai_log.h"

static const char *TAG = "GEMINAI_4G_AP";

static modem_wifi_config_t s_modem_wifi_config = MODEM_WIFI_DEFAULT_CONFIG();

char *get_ap_ssid(void)
{
    return s_modem_wifi_config.ssid;
}

/*modem 事件回调函数*/
static void on_modem_event(void *arg, esp_event_base_t event_base,
                           int32_t event_id, void *event_data)
{
    if (event_base == MODEM_BOARD_EVENT) {
        if (event_id == MODEM_EVENT_SIMCARD_DISCONN) {
            GEMINAI_LOGW(TAG, "Modem Board Event: SIM Card disconnected");
            setdown_selfcheck_lte_flag();
        } else if (event_id == MODEM_EVENT_SIMCARD_CONN) {
            GEMINAI_LOGI(TAG, "Modem Board Event: SIM Card Connected");
        } else if (event_id == MODEM_EVENT_DTE_DISCONN) {
            setdown_selfcheck_lte_flag();
            GEMINAI_LOGW(TAG, "Modem Board Event: USB disconnected");
        } else if (event_id == MODEM_EVENT_DTE_CONN) {
            GEMINAI_LOGI(TAG, "Modem Board Event: USB connected");
        } else if (event_id == MODEM_EVENT_NET_CONN) {
            GEMINAI_LOGI(TAG, "Modem Board Event: Network connected");
            GEMINAI_LOGI(TAG, "Now about to get accurcate time from sntp");
            sntp_task_start();
            //mqtt连接  
            mqtt_task_start();
            setup_selfcheck_lte_flag();
        } else if (event_id == MODEM_EVENT_NET_DISCONN) {
            setdown_selfcheck_lte_flag();
            GEMINAI_LOGW(TAG, "Modem Board Event: Network disconnected");
        } else if (event_id == MODEM_EVENT_WIFI_STA_CONN) {
            GEMINAI_LOGI(TAG, "Modem Board Event: Station connected");
        } else if (event_id == MODEM_EVENT_WIFI_STA_DISCONN) {
            GEMINAI_LOGW(TAG, "Modem Board Event: All stations disconnected");
        }
    }
}

#if 0
void modem_ap_task(void *pvParameters)
{
    bsp_usb_mode_select_host();
    bsp_usb_host_power_mode(BSP_USB_HOST_POWER_MODE_USB_DEV, true);


    /* Waiting for modem powerup */
    GEMINAI_LOGI(TAG, "====================================");
    GEMINAI_LOGI(TAG, "     ESP 4G Cat.1 Wi-Fi Router");
    GEMINAI_LOGI(TAG, "====================================");

    /* Initialize modem board. Dial-up internet */
    modem_config_t modem_config = MODEM_DEFAULT_CONFIG();
    modem_config.handler = on_modem_event;
    modem_board_init(&modem_config);


    esp_netif_t *ap_netif = modem_wifi_ap_init();
    assert(ap_netif != NULL);
    ESP_ERROR_CHECK(modem_wifi_set(&s_modem_wifi_config));

   
    uint32_t ap_dns_addr = 0;
    while (1) {

        // If manual DNS not defined, set DNS when got address, user better to add a queue to handle this

        esp_netif_dns_info_t dns;
        modem_board_get_dns_info(ESP_NETIF_DNS_MAIN, &dns);
        uint32_t _ap_dns_addr = dns.ip.u_addr.ip4.addr;
        if (_ap_dns_addr != ap_dns_addr) {
            modem_wifi_set_dns(ap_netif, _ap_dns_addr);
            ap_dns_addr = _ap_dns_addr;
            GEMINAI_LOGI(TAG, "changed: ap dns addr (auto): %s", inet_ntoa(ap_dns_addr));
        }


        vTaskDelay(pdMS_TO_TICKS(30000));
    }
}
#endif

void modem_ap_task(void *pvParameters)
{
    bsp_usb_mode_select_host();
    // bsp_usb_host_power_mode(BSP_USB_HOST_POWER_MODE_USB_DEV, true);


    /* Waiting for modem powerup */
    GEMINAI_LOGI(TAG, "====================================");
    GEMINAI_LOGI(TAG, "     ESP 4G Cat.1 Wi-Fi Router");
    GEMINAI_LOGI(TAG, "====================================");

    /* Initialize modem board. Dial-up internet */
    modem_config_t modem_config = MODEM_DEFAULT_CONFIG();
    modem_config.handler = on_modem_event;
    modem_board_init(&modem_config);


    esp_netif_t *ap_netif = modem_wifi_ap_init();
    assert(ap_netif != NULL);
    
// 修改wifi ssid
    while(base_station.wifi_mac[0] == 0){
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
    memset(s_modem_wifi_config.ssid, 0, sizeof(s_modem_wifi_config.ssid));
    sprintf(s_modem_wifi_config.ssid, "GeminAI-%02X%02X%02X%02X%02X%02X", 
            base_station.wifi_mac[0], base_station.wifi_mac[1], base_station.wifi_mac[2], 
            base_station.wifi_mac[3], base_station.wifi_mac[4], base_station.wifi_mac[5]);
    s_modem_wifi_config.channel = 11;
    // ESP_ERROR_CHECK(modem_wifi_set(&s_modem_wifi_config));


    struct esp_ip4_addr ap_ip;
    ap_ip.addr=0;
    ap_ip.addr=wifi_ap_get_local_ip(NULL);
    char ip_str[32]={0};
    while(ap_ip.addr==0)
    {
        vTaskDelay(200 / portTICK_PERIOD_MS);
        ap_ip.addr=wifi_ap_get_local_ip(NULL);
    }
    GEMINAI_LOGI(TAG, "got ip:" IPSTR, IP2STR(&ap_ip));
    inet_ntop(AF_INET, (void *)&(ap_ip.addr), ip_str, 16);
    //sshd_task_start(ip_str);
    // vTaskDelay(30000 / portTICK_PERIOD_MS);
    // modbus_task_start();


    uint32_t ap_dns_addr = 0;
    while (1) {

        // If manual DNS not defined, set DNS when got address, user better to add a queue to handle this

        esp_netif_dns_info_t dns;
        modem_board_get_dns_info(ESP_NETIF_DNS_MAIN, &dns);
        uint32_t _ap_dns_addr = dns.ip.u_addr.ip4.addr;
        if (_ap_dns_addr != ap_dns_addr) {
            modem_wifi_set_dns(ap_netif, _ap_dns_addr);
            ap_dns_addr = _ap_dns_addr;
            GEMINAI_LOGI(TAG, "changed: ap dns addr (auto): %s", inet_ntoa(ap_dns_addr));
        }


        vTaskDelay(pdMS_TO_TICKS(30000));
    }
}

/*4G 拨号上网并初始化为wifi ap主任务*/
void modem_ap_task_start()
{
    xTaskCreate(modem_ap_task, "modem_ap_task", 8192, NULL, 12, NULL);
}

void modem_lte_task(void *pvParameters)
{
    bsp_usb_mode_select_host();

    /* Waiting for modem powerup */
    GEMINAI_LOGI(TAG, "====================================");
    GEMINAI_LOGI(TAG, "     ESP 4G Cat.1 modem_lte_task");
    GEMINAI_LOGI(TAG, "====================================");

    /* Initialize modem board. Dial-up internet */
    modem_config_t modem_config = MODEM_DEFAULT_CONFIG();
    modem_config.handler = on_modem_event;
    modem_board_init(&modem_config);


    while (1) {
        esp_netif_dns_info_t dns;
        modem_board_get_dns_info(ESP_NETIF_DNS_MAIN, &dns);

        vTaskDelay(pdMS_TO_TICKS(30000));
    }
}

/*4G 拨号上网*/
void modem_lte_task_start()
{
    xTaskCreate(modem_lte_task, "modem_lte_task", 4096, NULL, 12, NULL);
}